/*
 *  This sketch sends data via HTTP GET requests to data.sparkfun.com service.
 *
 *  You need to get streamId and privateKey at data.sparkfun.com and paste them
 *  below. Or just customize this script to talk to other HTTP servers.
 *
 */
#include <Button2.h>
#include<stdlib.h>
#include <TFT_eSPI.h>
#include <math.h>
#include "bufferTFT.h"
typedef struct{
  float x;
  u_char height;

} Pillar;
typedef struct{
  float y;
  float speed;

} Bird;

unsigned short buffer[32400]={0};
TFT_eSPI tft = TFT_eSPI(135, 240); // Invoke custom library
Button2 btn1(0);
#define ScreenH (240)
#define ScreenW (135)
#define KongxiHeight (70)
#define PillarW (20)
#define MinSpeed (-10)
#define birdW (5)
#define birdX (ScreenW/2)

int PillarSpace=60;
Pillar pillars[3]={
  {0,50},
  {-50-PillarW,60},
  {-100-PillarW*2,70}
};
Bird bird ={ScreenH/2,0};
bool dead=false;
int score=0;

void initTFT(){
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor(0, 0);
  tft.setTextDatum(MC_DATUM);
  tft.setTextSize(3);
  
  if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
     pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode
     digitalWrite(TFT_BL, LOW); // Turn backlight on. TFT_BACKLIGHT_ON has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
   }
}


void setup()
{
    initTFT();
    btn1.setPressedHandler([](Button2 & b) {
      bird.speed-=5;
      if(bird.speed<MinSpeed)bird.speed=MinSpeed;
    });

    Serial.begin(115200);
    delay(10);
    
    // We start by connecting to a WiFi network

    Serial.println();

    tft.fillScreen(TFT_BLACK);
    tft.setTextDatum(MC_DATUM);
    tft.setRotation(3);
    tft.setTextColor(TFT_GREENYELLOW);
    tft.drawString("Starting", tft.width() / 2, tft.height() / 2);
    delay(3000);
    tft.setTextColor(TFT_PURPLE);
    tft.setTextSize(1);
}

void drawRectToBuffer(int x,int y,int w,int h,u_short color){
  int i,j;
  if(x<0){
    w=w+x;
    x=0;
  }
  if(y<0){
    h=h+y;
    y=0;
  }
  if(x+w>ScreenW){//修正超出范围
    w=ScreenW-x;
  }
  if(y+h>ScreenH){//修正超出范围
    h=ScreenH-y;
  }
  for(i=0;i<h;i++){
    for(j=0;j<w;j++){
      buffer[(j+x)*ScreenH+(i+y)]=color;

    }
  }

}
u_char lastPillar=0;
void judgeColid(){
  u_char curPillar=0;

  if(pillars[0].x+PillarW>=birdX&&pillars[0].x<=birdX||pillars[0].x+PillarW>=birdX+birdW&&pillars[0].x<=birdX+birdW){
    curPillar=1;
  }else if(pillars[1].x+PillarW>=birdX&&pillars[1].x<=birdX||pillars[1].x+PillarW>=birdX+birdW&&pillars[1].x<=birdX+birdW){
    curPillar=2;
  }else if(pillars[2].x+PillarW>=birdX&&pillars[2].x<=birdX||pillars[2].x+PillarW>=birdX+birdW&&pillars[2].x<=birdX+birdW){
    curPillar=3;
  }
  if(lastPillar&&(!curPillar)){
    score++;
  }
  lastPillar=curPillar;
  if(curPillar){
    if(bird.y<=ScreenH - pillars[curPillar-1].height -KongxiHeight){
      dead=true;
    }else if(bird.y+birdW>=ScreenH - pillars[curPillar-1].height){
      dead=true;
    }
  }else{
    if(bird.y<0||bird.y+birdW>=ScreenH){
      dead=true;
    }
  }
}
void updateBird(){
  bird.speed+=0.15f;
  bird.speed-=0.015f*(bird.speed*abs(bird.speed));
  bird.y+=bird.speed;
}
void updatePillars(){
  pillars[0].x+=0.6f;
  pillars[1].x+=0.6f;
  pillars[2].x+=0.6f;
  if(pillars[0].x>=ScreenW){
    pillars[0].x=pillars[2].x-PillarSpace-PillarW;
    pillars[0].height=rand()%160+20;
  }
  if(pillars[1].x>=ScreenW){
    pillars[1].x=pillars[0].x-PillarSpace-PillarW;
    pillars[1].height=rand()%160+20;
  }
  if(pillars[2].x>=ScreenW){
    pillars[2].x=pillars[1].x-PillarSpace-PillarW;
    pillars[2].height=rand()%160+20;
  }
}
void loop()
{
  btn1.loop();
  memset(buffer,0,sizeof(buffer));
  
  drawRectToBuffer(pillars[0].x,ScreenH-pillars[0].height,PillarW,pillars[0].height,0xffff);
  drawRectToBuffer(pillars[1].x,ScreenH-pillars[1].height,PillarW,pillars[1].height,0xffff);
  drawRectToBuffer(pillars[2].x,ScreenH-pillars[2].height,PillarW,pillars[2].height,0xffff);

  drawRectToBuffer(pillars[0].x,0,PillarW,ScreenH-pillars[0].height-KongxiHeight,0xffff);
  drawRectToBuffer(pillars[1].x,0,PillarW,ScreenH-pillars[1].height-KongxiHeight,0xffff);
  drawRectToBuffer(pillars[2].x,0,PillarW,ScreenH-pillars[2].height-KongxiHeight,0xffff);
  if(!dead){
    drawRectToBuffer(birdX,(int)bird.y,birdW,birdW,0xFFE0);
    updatePillars();
    updateBird();
    judgeColid();

  }else{
    drawRectToBuffer(birdX,(int)bird.y,birdW,birdW,0xF800);
  }
 
  tft.pushImage(0,0,240,135,buffer);
  tft.drawString((String)"score "+score,0,0,4);
}